package com.zelix.bean;

import com.arthas.client.ArthasClient;
import com.arthas.client.ArthasTool;
import com.zelix.tool.AnalyTool;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.jar.JarFile;

public class ZelixAnaly {
    /**
     *
     */
    private String jarPath;
    /**
     *
     */
    private String keyPath;
    /**
     *
     */
    private JarFile jarFile;
    /**
     *
     */
    private HashSet<String> keys;

    /**
     * Zelix分析类
     *
     * @param jarPath 待分析zkm.jar路径
     * @param keyPath 拦截的long值的key文件,单个方法分析可为null
     */
    public ZelixAnaly(String jarPath, String keyPath) {
        this.jarPath = jarPath;
        this.keyPath = keyPath;
        try {
            this.jarFile = new JarFile(jarPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (keyPath != null) {
            this.keys = AnalyTool.getKeys(keyPath);
        }
    }

    /**
     * 批量分析所有拦截到的方法
     */
    public void analy() {
        if (this.keyPath == null) {
            System.out.println("keyPath路径未指定,无法批量解析.");
            return;
        }
        ArthasClient client = ArthasTool.getClient();
        if (client == null) {
            return;
        }
        try {
            for (String key : keys) {
                AnalyTool.analy(client, jarFile, new AnalyMethod(key));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        client.disconnect();
    }

    /**
     * 单独分析一个方法
     *
     * @param method
     */
    public void analy(AnalyMethod method) {
        ArthasClient client = ArthasTool.getClient();
        if (client == null) {
            return;
        }
        try {
            AnalyTool.analy(client, jarFile, method);
        } catch (IOException e) {
            e.printStackTrace();
        }
        client.disconnect();
    }

    /**
     * 单个类批量转换,主要是把方法放到同一个类种处理,以免重复处理,结果修改被覆盖,只有一个方法被修改
     *
     * @param cls 类
     */
    public void convert(String cls) {
        if (this.keyPath == null) {
            System.out.println("keyPath路径未指定,无法批量转换.");
            return;
        }
        ArthasClient client = ArthasTool.getClient();
        if (client == null) {
            return;
        }

        AnalyClass analyClass = AnalyTool.getAnalyClass(cls, keys);

        try {
            AnalyTool.convert(client, jarFile, analyClass);
        } catch (IOException e) {
            e.printStackTrace();
        }

        client.disconnect();
    }

    /**
     * 所有类批量转换,主要是把方法放到同一个类种处理,以免重复处理,结果修改被覆盖,只有一个方法被修改
     */
    public void convert() {
        if (this.keyPath == null) {
            System.out.println("keyPath路径未指定,无法批量转换.");
            return;
        }
        ArthasClient client = ArthasTool.getClient();
        if (client == null) {
            return;
        }

        HashMap<String, AnalyClass> classes = AnalyTool.getAnalyClass(keys);
        try {
            for (String key : classes.keySet()) {
                AnalyTool.convert(client, jarFile, classes.get(key));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        client.disconnect();
    }
}
